package com.hetang.maijiayun.report.service;

import java.math.BigDecimal;
import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;

import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.alibaba.fastjson.JSONObject;
import com.hetang.maijiayun.api.report.ISkuSaleReportService;
import com.hetang.maijiayun.api.report.model.SkuSaleReport;
import com.hetang.maijiayun.api.report.model.SkuSaleReportDetail;
import com.hetang.maijiayun.api.report.model.SkuSaleCustomerReport;
import com.hetang.maijiayun.api.util.APIException;
import com.hetang.maijiayun.api.util.JOHelper;
import com.hetang.maijiayun.api.util.Page;
import com.hetang.maijiayun.api.util.PageResultSet;
import com.hetang.maijiayun.report.mappers.SkuSaleReportMapper;
import com.hetang.maijiayun.report.utils.CustomerContextHolder;
import com.hetang.maijiayun.utils.security.SecuritySession;

/**
 * 商品销售报表
 * 
 * @author yangfan
 */
@Service("skuSaleReportService")
public class SkuSaleReportServiceImpl implements ISkuSaleReportService {
	@Autowired
	SkuSaleReportMapper skuSaleReportMapper;

	public static final Logger logger = LoggerFactory.getLogger(SkuSaleReportServiceImpl.class);

	/**
	 * 商品销售统计列表
	 * 支持查询条件(实时查询)
	 * 1.店铺 eshopCodes
	 * 2.订单状态orderStatus
	 * 3.下单时间create_time 4.付款时间payment_time  5.发货时间delivery_time
	 * 6.品牌brandIds 7.分类categoryIds 8.商品名称goodsName 9.商品货号
	 * 10.仓库warehouseIds
	 * 11.sku编码
	 * 12.支持按照 货号、销量、销售额、毛利、毛利率 排序
	 * 
	 */
	@Override
	public PageResultSet<SkuSaleReportDetail> getSkuSaleReportDetail(JSONObject param, SecuritySession session) throws APIException {
		if (Objects.isNull(param)) {
			APIException.builder().illegalArgError().errorMsg("查询参数不能为空").throwExcetion();
		}
		CustomerContextHolder.setCustomerType(CustomerContextHolder.DATA_SOURCE_SLAVE);
		param.put("tenantryId", session.tenantry.id);
		// 查询总条数
		Integer totalNum = skuSaleReportMapper.countSkuSaleReportDetail(param);
		// 根据分页参数生成limit所需数据
		Integer pageNo = param.getInteger("pageNo") == null ? 1 : param.getInteger("pageNo");
		Integer pageSize = param.getInteger("pageSize") == null ? 50 : param.getInteger("pageSize");
		List<SkuSaleReportDetail> reportDatas = new ArrayList<SkuSaleReportDetail>();
		if(totalNum > 0){
			param.put("pageLimitClause", (pageNo - 1) * pageSize + "," + pageSize);
			// 查出满足条件的sku的销售数据列表
			reportDatas = skuSaleReportMapper.getSkuSaleReportDetail(param);
		}
		// 返回前端
		return new PageResultSet<SkuSaleReportDetail>(new Page(pageNo, pageSize), totalNum, reportDatas);
	}
	
	/**
	 * 商品销售统计汇总
	 */
	@Override
	public SkuSaleReport getSkuSaleReport(JSONObject param, SecuritySession session) throws APIException {
		if (Objects.isNull(param)) {
			param = new JSONObject();
		}
		CustomerContextHolder.setCustomerType(CustomerContextHolder.DATA_SOURCE_SLAVE);
		param.put("tenantryId", session.tenantry.id);
		return skuSaleReportMapper.getSkuSaleReport(param);
	}
	
	/**
	 * 商品销售统计列表钻取数据
	 */
	@Override
	public PageResultSet<SkuSaleCustomerReport> drillSkuSaleReportByCustomer(JSONObject param, SecuritySession session) throws APIException {
		if (Objects.isNull(param)) {
			APIException.builder().illegalArgError().errorMsg("查询参数不能为空").throwExcetion();
		}
		CustomerContextHolder.setCustomerType(CustomerContextHolder.DATA_SOURCE_SLAVE);
		param.put("tenantryId", session.tenantry.id);
		// 根据分页参数生成limit所需数据
		Integer pageNo = param.getInteger("pageNo") == null ? 1 : param.getInteger("pageNo");
		Integer pageSize = param.getInteger("pageSize") == null ? 50 : param.getInteger("pageSize");
		// 查询总条数
		Integer totalNum = skuSaleReportMapper.countSkuSaleCustomerReport(param);
		if(totalNum == 0){
			return new PageResultSet<SkuSaleCustomerReport>(new Page(pageNo, pageSize), 0, new ArrayList<SkuSaleCustomerReport>());
		}
		String pageLimitClause = (pageNo - 1) * pageSize + "," + pageSize;
		param.put("pageLimitClause", pageLimitClause);
		// 查出选择日期内,每天的统计数据
		List<SkuSaleCustomerReport> reportDatas = skuSaleReportMapper.getSkuSaleCustomerReport(param);
		return new PageResultSet<SkuSaleCustomerReport>(new Page(pageNo,pageSize), totalNum, reportDatas);
	}

	@Override
	public List<JSONObject> getOrderDailySale(JSONObject param, SecuritySession session) throws APIException {
		//根据下单时间or付款时间or发货时间/仓库/店铺 三个查询条件,查询订单总数以及订单销售额
		if(Objects.isNull(param) || StringUtils.isBlank(param.getString("timeType")) 
				|| StringUtils.isBlank(param.getString("startTime")) || StringUtils.isBlank(param.getString("endTime"))){
			APIException.builder().illegalArgError().errorMsg("查询时间类型以及时间段不能为空").throwExcetion();
		}
		CustomerContextHolder.setCustomerType(CustomerContextHolder.DATA_SOURCE_ETL);
		param.put("tenantryId", session.tenantry.id);
		try{
			//TODO 验证时间区间不能大于一个月
			DateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
			Date startTime = sdf.parse(param.getString("startTime"));
			Date endTime = sdf.parse(param.getString("endTime"));
			
			//String key = getKey(param);
			if(endTime.getTime() - startTime.getTime() > 1000*3600*24*31L){
				throw APIException.builder().illegalArgError().errorMsg("统计日期区间不能超过一个月").build();
			}
			// 处理某些天没有数据的情况(FIXME 效率相当的情况下,mysql处理当然更改)
			logger.info("#getOrderDailySale#param:{}",param);
			List<JSONObject> datas = skuSaleReportMapper.getOrderDailySale(param);
			logger.info("#getOrderDailySale#datas:{}",datas);
			Map<String,JSONObject> dateDataMap = new HashMap<>();
			for (JSONObject data : datas) {
				dateDataMap.put(data.getString("reportDate"), data);
			}
			
			Calendar startCal = Calendar.getInstance();
			startCal.setTime(startTime);
			
			Calendar endCal = Calendar.getInstance();
			endCal.setTime(endTime);
			
			List<JSONObject> ret = new ArrayList<>();//需要统计日期升序
			while(startCal.compareTo(endCal) <= 0){
				String key = sdf.format(startCal.getTime());
				if(!dateDataMap.containsKey(key)){
					ret.add(JOHelper.gen("reportDate",key,"orderQuantity",0,"saleAmount",BigDecimal.ZERO));
				}else{
					ret.add(dateDataMap.get(key));
				}
				startCal.add(Calendar.DATE, 1);
			}
			
			return ret;
		}catch (ParseException e) {
			throw APIException.builder().illegalArgError().errorMsg("日期格式错误").build();
		}
	}

	@Override
	public List<JSONObject> getCategorySaleRank(JSONObject param, SecuritySession session)
			throws APIException {
		if(Objects.isNull(param) || StringUtils.isBlank(param.getString("timeType")) 
				|| StringUtils.isBlank(param.getString("startTime")) || StringUtils.isBlank(param.getString("endTime"))){
			APIException.builder().illegalArgError().errorMsg("查询时间类型以及时间段不能为空").throwExcetion();
		}
		CustomerContextHolder.setCustomerType(CustomerContextHolder.DATA_SOURCE_SLAVE);
		param.put("tenantryId", session.tenantry.id);
		List<JSONObject> ret = skuSaleReportMapper.getCategorySaleRank(param);
		dealPercent(ret, param);
		return ret;
	}
	
	@Override
	public List<JSONObject> getAreaSaleRank(JSONObject param, SecuritySession session) throws APIException {
		if(Objects.isNull(param) || StringUtils.isBlank(param.getString("timeType")) 
				|| StringUtils.isBlank(param.getString("startTime")) || StringUtils.isBlank(param.getString("endTime"))){
			APIException.builder().illegalArgError().errorMsg("查询时间类型以及时间段不能为空").throwExcetion();
		}
		CustomerContextHolder.setCustomerType(CustomerContextHolder.DATA_SOURCE_SLAVE);
		param.put("tenantryId", session.tenantry.id);
		List<JSONObject> ret = skuSaleReportMapper.getAreaSaleRank(param);
		dealPercent(ret, param);
		return ret;
	}
	
	@Override
	public List<JSONObject> getBrandSaleRank(JSONObject param, SecuritySession session) throws APIException {
		if(Objects.isNull(param) || StringUtils.isBlank(param.getString("timeType")) 
				|| StringUtils.isBlank(param.getString("startTime")) || StringUtils.isBlank(param.getString("endTime"))){
			APIException.builder().illegalArgError().errorMsg("查询时间类型以及时间段不能为空").throwExcetion();
		}
		CustomerContextHolder.setCustomerType(CustomerContextHolder.DATA_SOURCE_SLAVE);
		param.put("tenantryId", session.tenantry.id);
		List<JSONObject> ret = skuSaleReportMapper.getBrandSaleRank(param);
		dealPercent(ret, param);
		return ret;
	}
	
	@Override
	public List<JSONObject> getSkuSaleRank(JSONObject param, SecuritySession session) throws APIException {
		if(Objects.isNull(param) || StringUtils.isBlank(param.getString("timeType")) 
				|| StringUtils.isBlank(param.getString("startTime")) || StringUtils.isBlank(param.getString("endTime"))){
			APIException.builder().illegalArgError().errorMsg("查询时间类型以及时间段不能为空").throwExcetion();
		}
		CustomerContextHolder.setCustomerType(CustomerContextHolder.DATA_SOURCE_SLAVE);
		param.put("tenantryId", session.tenantry.id);
		param.put("sort", "desc");
		List<JSONObject> ret = skuSaleReportMapper.getSkuSaleRank(param);
		
		param.put("sort", "asc");
		List<JSONObject> bottom5 = skuSaleReportMapper.getSkuSaleRank(param);
		
		ret.addAll(bottom5);
		dealPercent(ret, param);
		return ret;
	}

	private void dealPercent(List<JSONObject> data, JSONObject param) {
		if(CollectionUtils.isEmpty(data)){
			return;
		}
		JSONObject sum = skuSaleReportMapper.getSumSale(param);//计算百分比
		for (JSONObject detail : data) {
			if(Objects.isNull(sum) || Objects.isNull(sum.getBigDecimal("saleAmt"))
					|| BigDecimal.ZERO.compareTo(sum.getBigDecimal("saleAmt")) ==0){
				detail.put("saleAmtP",new BigDecimal(100.00));
			}else{
				detail.put("saleAmtP", detail.getBigDecimal("saleAmt").divide(sum.getBigDecimal("saleAmt"), 4, BigDecimal.ROUND_UP).multiply(new BigDecimal(100)));
			}
			if(Objects.isNull(sum) || Objects.isNull(sum.getBigDecimal("skuQuantity"))
					|| BigDecimal.ZERO.compareTo(sum.getBigDecimal("skuQuantity")) ==0){
				detail.put("skuQuantityP",new BigDecimal(100.00));
			}else{
				detail.put("skuQuantityP", detail.getBigDecimal("skuQuantity").divide(sum.getBigDecimal("skuQuantity"), 4, BigDecimal.ROUND_UP).multiply(new BigDecimal(100)));
			}
		}
	}

	@Override
	public List<Long> getSaleTopSkuIds(Integer topNum, String supplierCode, SecuritySession session) throws APIException {
		if(Objects.isNull(topNum)){
			APIException.builder().illegalArgError().errorMsg("查询数量不能为空").throwExcetion();
		}
		// FIXME TODO 考虑搞成注解的方式
		CustomerContextHolder.setCustomerType(CustomerContextHolder.DATA_SOURCE_SLAVE);
		return skuSaleReportMapper.getSaleTopSkuIds(topNum,supplierCode,session.tenantry.id);
	}

}
